};
/**
- * @workspaceNum: Workspace index
- * @parentActor: The actor which will be the parent of this workspace;
- * we need this in order to add chrome such as the icons
- * on top of the windows without having them be scaled.
+ * @metaWorkspace: a #Meta.Workspace
*/
-function Workspace(workspaceNum, parentActor) {
- this._init(workspaceNum, parentActor);
+function Workspace(metaWorkspace) {
+ this._init(metaWorkspace);
}
Workspace.prototype = {
- _init : function(workspaceNum, parentActor) {
+ _init : function(metaWorkspace) {
// When dragging a window, we use this slot for reserve space.
this._reservedSlot = null;
- this.workspaceNum = workspaceNum;
+ this.metaWorkspace = metaWorkspace;
this._windowOverlaysGroup = new Clutter.Group();
// Without this the drop area will be overlapped.
this._windowOverlaysGroup.set_size(0, 0);
- this._metaWorkspace = global.screen.get_workspace_by_index(workspaceNum);
-
- parentActor.add_actor(this._windowOverlaysGroup);
- this._parentActor = parentActor;
-
this.actor = new Clutter.Group();
this.actor._delegate = this;
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
+ // Items in _windowOverlaysGroup should not be scaled, so we don't
+ // add them to this.actor, but to its parent whenever it changes
+ this.actor.connect('parent-set', Lang.bind(this, this._onParentSet));
+
// Auto-sizing is unreliable in the presence of ClutterClone, so rather than
// implicitly counting on the workspace actor to be sized to the size of the
// included desktop actor clone, set the size explicitly to the screen size.
// We check for "2" here because the Desktop does not really count
// as a window in this context.
if (this._windows.length <= 2) {
- this._metaWorkspace.activate(time);
+ this.metaWorkspace.activate(time);
Main.overview.hide();
}
}));
this._showOnlyWindows = null;
// Track window changes
- this._windowAddedId = this._metaWorkspace.connect('window-added',
+ this._windowAddedId = this.metaWorkspace.connect('window-added',
Lang.bind(this, this._windowAdded));
- this._windowRemovedId = this._metaWorkspace.connect('window-removed',
+ this._windowRemovedId = this.metaWorkspace.connect('window-removed',
Lang.bind(this, this._windowRemoved));
this._repositionWindowsId = 0;
return -1;
},
+ _onParentSet: function(actor, old_parent) {
+ let new_parent = this.actor.get_parent();
+ if (new_parent == null)
+ return;
+
+ if (old_parent)
+ this._windowOverlaysGroup.reparent(new_parent);
+ else
+ new_parent.add_actor(this._windowOverlaysGroup);
+ },
+
/**
* lookupCloneForMetaWindow:
* @metaWindow: A #MetaWindow
}
},
+ /**
+ * setReactive:
+ * @reactive: %true iff the workspace should be reactive
+ *
+ * Set the workspace (desktop) reactive
+ **/
+ setReactive: function(reactive) {
+ this._desktop.actor.reactive = reactive;
+ },
+
_updateFramePosition : function() {
this._frame.set_position(this._desktop.actor.x - FRAME_SIZE / this.actor.scale_x,
this._desktop.actor.y - FRAME_SIZE / this.actor.scale_y);
},
// Animate the full-screen to Overview transition.
- zoomToOverview : function(animate) {
+ zoomToOverview : function() {
this.actor.set_position(this.gridX, this.gridY);
this.actor.set_scale(this.scale, this.scale);
// Position and scale the windows.
- if (animate)
+ if (Main.overview.animationInProgress)
this.positionWindows(WindowPositionFlags.ANIMATE | WindowPositionFlags.ZOOM);
else
this.positionWindows(WindowPositionFlags.ZOOM);
- let active = global.screen.get_active_workspace_index();
- let fadeInIcons = (animate &&
- active == this.workspaceNum &&
+ let active = global.screen.get_active_workspace();
+ let fadeInIcons = (Main.overview.animationInProgress &&
+ active == this.metaWorkspace &&
!this._haveMaximizedWindows());
this._desktop.zoomToOverview(fadeInIcons);
}
}
- let active = global.screen.get_active_workspace_index();
- let fadeOutIcons = (active == this.workspaceNum &&
+ let active = global.screen.get_active_workspace();
+ let fadeOutIcons = (active == this.metaWorkspace &&
!this._haveMaximizedWindows());
this._desktop.zoomFromOverview(fadeOutIcons);
}
Tweener.removeTweens(actor);
- this._metaWorkspace.disconnect(this._windowAddedId);
- this._metaWorkspace.disconnect(this._windowRemovedId);
+ this.metaWorkspace.disconnect(this._windowAddedId);
+ this.metaWorkspace.disconnect(this._windowRemovedId);
if (this._repositionWindowsId > 0)
Mainloop.source_remove(this._repositionWindowsId);
// Tests if @win belongs to this workspaces
_isMyWindow : function (win) {
- return win.get_workspace() == this.workspaceNum ||
+ return win.get_workspace() == this.metaWorkspace.index() ||
(win.get_meta_window() && win.get_meta_window().is_on_all_workspaces());
},
},
_onCloneSelected : function (clone, time) {
- Main.activateWindow(clone.metaWindow, time, this.workspaceNum);
+ Main.activateWindow(clone.metaWindow, time,
+ this.metaWorkspace.index());
},
_removeSelf : function(actor, event) {
- let screen = global.screen;
- let workspace = screen.get_workspace_by_index(this.workspaceNum);
-
- screen.remove_workspace(workspace, event.get_time());
+ screen.remove_workspace(this.metaWorkspace, event.get_time());
return true;
},
};
let metaWindow = win.get_meta_window();
- metaWindow.change_workspace_by_index(this.workspaceNum,
+ metaWindow.change_workspace_by_index(this.metaWorkspace.index(),
false, // don't create workspace
time);
return true;
} else if (source.shellWorkspaceLaunch) {
- this._metaWorkspace.activate(time);
+ this.metaWorkspace.activate(time);
source.shellWorkspaceLaunch();
return true;
}
const WORKSPACE_DRAG_THRESHOLD = 0.2;
-function GenericWorkspacesView(width, height, x, y, animate) {
- this._init(width, height, x, y, animate);
+function GenericWorkspacesView(width, height, x, y, workspaces) {
+ this._init(width, height, x, y, workspaces);
}
GenericWorkspacesView.prototype = {
- _init: function(width, height, x, y, animate) {
+ _init: function(width, height, x, y, workspaces) {
this.actor = new St.Bin({ style_class: "workspaces" });
this._actor = new Clutter.Group();
this._spacing = 0;
this._windowSelectionAppId = null;
-
- this._workspaces = [];
-
this._highlightWindow = null;
let activeWorkspaceIndex = global.screen.get_active_workspace_index();
+ this._workspaces = workspaces;
- // Create and position workspace objects
- for (let w = 0; w < global.screen.n_workspaces; w++) {
- this._addWorkspaceActor(w);
- }
+ // Add workspace actors
+ for (let w = 0; w < global.screen.n_workspaces; w++)
+ this._workspaces[w].actor.reparent(this._actor);
this._workspaces[activeWorkspaceIndex].actor.raise_top();
// Position/scale the desktop windows and their children after the
Lang.bind(this, function() {
this._onRestacked();
for (let w = 0; w < this._workspaces.length; w++)
- this._workspaces[w].zoomToOverview(animate);
+ this._workspaces[w].zoomToOverview();
}));
- // Track changes to the number of workspaces
- this._nWorkspacesNotifyId =
- global.screen.connect('notify::n-workspaces',
- Lang.bind(this, this._workspacesChanged));
this._switchWorkspaceNotifyId =
global.window_manager.connect('switch-workspace',
Lang.bind(this, this._activeWorkspaceChanged));
},
_onDestroy: function() {
- for (let w = 0; w < this._workspaces.length; w++)
- this._workspaces[w].destroy();
- this._workspaces = [];
-
Main.overview.disconnect(this._overviewShowingId);
- global.screen.disconnect(this._nWorkspacesNotifyId);
global.window_manager.disconnect(this._switchWorkspaceNotifyId);
global.screen.disconnect(this._restackedNotifyId);
},
throw new Error("Not implemented");
},
- _positionWorkspaces: function() {
+ updateWorkspaces: function() {
throw new Error("Not implemented");
},
- _workspacesChanged: function() {
+ _positionWorkspaces: function() {
throw new Error("Not implemented");
},
_activeWorkspaceChanged: function() {
throw new Error("Not implemented");
- },
-
- _addWorkspaceActor: function() {
- throw new Error("Not implemented");
}
};
-function MosaicView(width, height, x, y, animate) {
- this._init(width, height, x, y, animate);
+function MosaicView(width, height, x, y, workspaces) {
+ this._init(width, height, x, y, workspaces);
}
MosaicView.prototype = {
__proto__: GenericWorkspacesView.prototype,
- _init: function(width, height, x, y, animate) {
- GenericWorkspacesView.prototype._init.call(this, width, height, x, y, animate);
+ _init: function(width, height, x, y, workspaces) {
+ GenericWorkspacesView.prototype._init.call(this, width, height, x, y, workspaces);
this.actor.style_class = "workspaces mosaic";
this._actor.set_clip(x - Workspace.FRAME_SIZE,
}
},
- _workspacesChanged: function() {
- let oldNumWorkspaces = this._workspaces.length;
- let newNumWorkspaces = global.screen.n_workspaces;
-
- if (oldNumWorkspaces == newNumWorkspaces)
- return;
-
+ updateWorkspaces: function(oldNumWorkspaces, newNumWorkspaces, lostWorkspaces) {
let oldScale = this._workspaces[0].scale;
let oldGridWidth = Math.ceil(Math.sqrt(oldNumWorkspaces));
let oldGridHeight = Math.ceil(oldNumWorkspaces / oldGridWidth);
- let lostWorkspaces = [];
- if (newNumWorkspaces > oldNumWorkspaces) {
- // Create new workspace groups
- for (let w = oldNumWorkspaces; w < newNumWorkspaces; w++) {
- this._addWorkspaceActor(w);
- }
-
- } else {
- // Truncate the list of workspaces
- // FIXME: assumes that the workspaces are being removed from
- // the end of the list, not the start/middle
- lostWorkspaces = this._workspaces.splice(newNumWorkspaces);
- }
+ // Add actors
+ if (newNumWorkspaces > oldNumWorkspaces)
+ for (let w = oldNumWorkspaces; w < newNumWorkspaces; w++)
+ this._actor.add_actor(this._workspaces[w].actor);
// Figure out the new layout
this._positionWorkspaces();
let workspace = lostWorkspaces[w];
workspace.slideOut(function () { workspace.destroy(); });
}
-
- // FIXME: deal with windows on the lost workspaces
}
// Reset the selection state; if we went from > 1 workspace to 1,
this._workspaces[to].setSelected(true);
},
- _addWorkspaceActor: function(workspaceNum) {
- let workspace = new Workspace.Workspace(workspaceNum, this._actor);
- this._workspaces[workspaceNum] = workspace;
- this._actor.add_actor(workspace.actor);
- },
-
createControllerBar: function() {
return null;
},
},
removeWorkspace: function() {
- let last = this._workspaces.length - 1;
- global.screen.remove_workspace(this._workspaces[last]._metaWorkspace,
+ let removedIndex = this._workspaces.length - 1;
+ let metaWorkspace = this._workspaces[removedIndex].metaWorkspace;
+ global.screen.remove_workspace(metaWorkspace,
global.get_current_time());
},
}
};
-function SingleView(width, height, x, y, animate) {
- this._init(width, height, x, y, animate);
+function SingleView(width, height, x, y, workspaces) {
+ this._init(width, height, x, y, workspaces);
}
SingleView.prototype = {
__proto__: GenericWorkspacesView.prototype,
- _init: function(width, height, x, y, animate) {
+ _init: function(width, height, x, y, workspaces) {
this._newWorkspaceArea = new NewWorkspaceArea();
this._leftShadow = new St.Bin({ style_class: 'left-workspaces-shadow',
width: Math.ceil(global.screen_width * WORKSPACE_SHADOW_SCALE),
height: global.screen_height,
x: global.screen_width })
- GenericWorkspacesView.prototype._init.call(this, width, height, x, y, animate);
+ GenericWorkspacesView.prototype._init.call(this, width, height, x, y, workspaces);
this._actor.add_actor(this._newWorkspaceArea.actor);
this._actor.add_actor(this._leftShadow);
this._buttonPressId = 0;
this._capturedEventId = 0;
this._timeoutId = 0;
+ this._windowDragBeginId = 0;
+ this._windowDragEndId = 0;
},
_positionWorkspaces: function() {
this._dragIndex = index;
this._buttonPressId = dragActor.connect('button-press-event',
Lang.bind(this, this._onButtonPress));
+ this._windowDragBeginId = this._workspaces[index].connect('window-drag-begin',
+ Lang.bind(this, this._onWindowDragBegin));
+ this._windowDragEndId = this._workspaces[index].connect('window-drag-end',
+ Lang.bind(this, this._onWindowDragEnd));
} else {
this._dragIndex = -1;
global.stage.disconnect(this._capturedEventId);
this._capturedEventId = 0;
}
+
+ if (this._windowDragBeginId > 0) {
+ this._workspaces[index].disconnect(this._windowDragBeginId);
+ this._windowDragBeginId = 0;
+ }
+
+ if (this._windowDragEndId > 0) {
+ this._workspaces[index].disconnect(this._windowDragEndId);
+ this._windowDragEndId = 0;
+ }
}
},
activate++;
if (activate != active) {
- let workspace = this._workspaces[activate]._metaWorkspace;
+ let workspace = this._workspaces[activate].metaWorkspace;
workspace.activate(global.get_current_time());
} else {
this._scrollToActive(true);
}
},
- _workspacesChanged: function() {
- let oldNumWorkspaces = this._workspaces.length;
- let newNumWorkspaces = global.screen.n_workspaces;
+ updateWorkspaces: function(oldNumWorkspaces, newNumWorkspaces, lostWorkspaces) {
let active = global.screen.get_active_workspace_index();
- if (oldNumWorkspaces == newNumWorkspaces)
- return;
-
if (this._scroll != null)
this._scroll.adjustment.upper = newNumWorkspaces;
if (newNumWorkspaces > oldNumWorkspaces) {
- // Create new workspace groups
for (let w = oldNumWorkspaces; w < newNumWorkspaces; w++)
- this._addWorkspaceActor(w);
+ this._actor.add_actor(this._workspaces[w].actor);
+
this._positionWorkspaces();
this._updateWorkspaceActors();
this._scrollScrollBarToIndex(active + 1, false);
-
} else {
- let active = global.screen.get_active_workspace_index();
- let removedNum = oldNumWorkspaces - newNumWorkspaces;
- let removedIndex = active + 1;
- this._lostWorkspaces = this._workspaces.splice(removedIndex,
- removedNum);
-
- // Don't let the user try to select this workspace as it's
- // making its exit.
- for (let l = 0; l < this._lostWorkspaces.length; l++)
- this._lostWorkspaces[l]._desktop.actor.reactive = false;
-
- // reassign workspaceNum and metaWorkspace, as lost workspaces
- // have not necessarily been removed from the end
- for (let i = removedIndex; i < this._workspaces.length; i++) {
- let metaWorkspace = global.screen.get_workspace_by_index(i);
- this._workspaces[i].workspaceNum = i;
- this._workspaces[i]._metaWorkspace = metaWorkspace;
- }
-
+ this._lostWorkspaces = lostWorkspaces;
this._scrollScrollBarToIndex(active, false);
this._scrollToActive(true);
}
},
_onWindowDragBegin: function(w, actor) {
- if (!this._scroll || this._scroll.adjustment.value - Math.round(this._scroll.adjustment.value) != 0)
+ if (!this._scroll || this._scrolling)
return;
this._inDrag = true;
let activeWorkspaceIndex = global.screen.get_active_workspace_index();
if (x == 0 && activeWorkspaceIndex > 0 && this._dragOverLastX !== 0) {
- this._workspaces[activeWorkspaceIndex - 1]._metaWorkspace.activate(global.get_current_time());
+ this._workspaces[activeWorkspaceIndex - 1].metaWorkspace.activate(global.get_current_time());
this._workspaces[activeWorkspaceIndex - 1].setReservedSlot(actor._delegate);
this._dragOverLastX = 0;
return;
}
if (x == global.screen_width - 1 && this._workspaces[activeWorkspaceIndex + 1] &&
this._dragOverLastX != global.screen_width - 1) {
- this._workspaces[activeWorkspaceIndex + 1]._metaWorkspace.activate(global.get_current_time());
+ this._workspaces[activeWorkspaceIndex + 1].metaWorkspace.activate(global.get_current_time());
this._workspaces[activeWorkspaceIndex + 1].setReservedSlot(actor._delegate);
this._dragOverLastX = global.screen_width - 1;
return;
this._timeoutId = Mainloop.timeout_add_seconds (1, Lang.bind(this, function() {
let i = global.screen.get_active_workspace_index();
if (this._workspaces[i + onPanel]) {
- this._workspaces[i + onPanel]._metaWorkspace.activate(global.get_current_time());
+ this._workspaces[i + onPanel].metaWorkspace.activate(global.get_current_time());
this._workspaces[i + onPanel].setReservedSlot(actor._delegate);
}
return true;
this._workspaces[i].setReservedSlot(null);
},
- _addWorkspaceActor: function(workspaceNum) {
- let workspace = new Workspace.Workspace(workspaceNum, this._actor);
- workspace.connect('window-drag-begin', Lang.bind(this, this._onWindowDragBegin));
- workspace.connect('window-drag-end', Lang.bind(this, this._onWindowDragEnd));
- this._actor.add_actor(workspace.actor);
- this._workspaces[workspaceNum] = workspace;
- },
-
// handle changes to the scroll bar's adjustment:
// sync the workspaces' positions to the position of the scroll bar handle
// and change the active workspace if appropriate
let current = Math.round(adj.value);
if (active != current) {
- let metaWorkspace = this._workspaces[current]._metaWorkspace;
+ let metaWorkspace = this._workspaces[current].metaWorkspace;
if (!this._scrolling) {
// This here is a little tricky - we get here when StScrollBar
activate--;
if (activate != current) {
- let metaWorkspace = this._workspaces[activate]._metaWorkspace;
+ let metaWorkspace = this._workspaces[activate].metaWorkspace;
metaWorkspace.activate(global.get_current_time());
}
},
}
actor.connect('clicked', Lang.bind(this, function() {
if (this._workspaces[i] != undefined)
- this._workspaces[i]._metaWorkspace.activate(global.get_current_time());
+ this._workspaces[i].metaWorkspace.activate(global.get_current_time());
}));
actor._delegate = {};
actor._delegate.acceptDrop = Lang.bind(this, function(source, actor, x, y, time) {
if (this._workspaces[i].acceptDrop(source, actor, x, y, time)) {
- this._workspaces[i]._metaWorkspace.activate(global.get_current_time());
+ this._workspaces[i].metaWorkspace.activate(global.get_current_time());
return true;
}
else
},
removeWorkspace: function() {
- let active = global.screen.get_active_workspace_index();
- global.screen.remove_workspace(this._workspaces[active]._metaWorkspace,
+ let removedIndex = global.screen.get_active_workspace_index();
+ let metaWorkspace = this._workspaces[removedIndex].metaWorkspace;
+ global.screen.remove_workspace(metaWorkspace,
global.get_current_time());
},
WorkspacesControls.prototype = {
_init: function() {
- this.actor = null;
+ this.actor = new St.BoxLayout({ style_class: 'workspaces-bar' });
this._gconf = Shell.GConf.get_default();
+
this._toggleViewButton = null;
this._addButton = null;
this._removeButton = null;
else
this._currentViewType = WorkspacesViewType.SINGLE;
- this._currentView = null;
- this._nWorkspacesNotifyId = 0;
- this._switchWorkspaceNotifyId = 0;
+ this._nWorkspacesNotifyId =
+ global.screen.connect('notify::n-workspaces',
+ Lang.bind(this, this._workspacesChanged));
+
+ this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
},
_updateToggleButtonStyle: function() {
this._currentViewType = view;
this._updateToggleButtonStyle();
this._gconf.set_string(WORKSPACES_VIEW_KEY, view);
- this.emit('view-changed');
- },
-
- createCurrentWorkspaceView: function(width, height, x, y, animate) {
- switch (this._currentViewType) {
- case WorkspacesViewType.SINGLE:
- this._currentView = new SingleView(width, height, x, y, animate);
- break;
- case WorkspacesViewType.GRID:
- default:
- this._currentView = new MosaicView(width, height, x, y, animate);
- break;
- }
- this._updateControlsBar();
- return this._currentView;
},
- _updateControlsBar: function() {
- if (this.actor)
- this.actor.remove_all();
- else
- this.actor = new St.BoxLayout({ style_class: 'workspaces-bar' });
+ updateControls: function(currentView) {
+ this.actor.remove_all();
// View switcher button
this._toggleViewButton = new St.Button();
this.actor.add(this._toggleViewButton, { y_fill: false, y_align: St.Align.START });
// View specific controls
- let bar = this._currentView.createControllerBar();
- if (!bar)
- bar = new St.Bin();
-
- this.actor.add(bar, { expand: true,
- x_fill: true,
- y_fill: true,
- y_align: St.Align.MIDDLE,
- x_align: St.Align.START });
+ let viewControls = currentView.createControllerBar();
+ if (!viewControls)
+ viewControls = new St.Bin();
+ this.actor.add(viewControls, { expand: true,
+ x_fill: true,
+ y_fill: true,
+ y_align: St.Align.MIDDLE,
+ x_align: St.Align.START });
// Add/remove workspace buttons
this._removeButton = new St.Button({ style_class: 'workspace-controls remove' });
this._removeButton.connect('clicked', Lang.bind(this, function() {
- this._currentView.removeWorkspace();
+ currentView.removeWorkspace();
}));
this.actor.add(this._removeButton, { y_fill: false,
y_align: St.Align.START });
this._addButton = new St.Button({ style_class: 'workspace-controls add' });
this._addButton.connect('clicked', Lang.bind(this, function() {
- this._currentView.addWorkspace()
+ currentView.addWorkspace()
}));
this._addButton._delegate = this._addButton;
this._addButton._delegate.acceptDrop = Lang.bind(this,
function(source, actor, x, y, time) {
- let view = this._currentView;
+ let view = currentView;
return view._acceptNewWorkspaceDrop(source, actor, x, y, time);
+return false;
});
this.actor.add(this._addButton, { y_fill: false,
y_align: St.Align.START });
- this._nWorkspacesNotifyId =
- global.screen.connect('notify::n-workspaces',
- Lang.bind(this, this._workspacesChanged));
-
- this._switchWorkspaceNotifyId =
- global.window_manager.connect('switch-workspace',
- Lang.bind(this, this._updateButtonSensitivity));
+ this._workspacesChanged();
+ },
- this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
+ setCanRemove: function(canRemove) {
+ this._setButtonSensitivity(this._removeButton, canRemove);
+ },
- this._workspacesChanged();
+ setCanAdd: function(canAdd) {
+ this._setButtonSensitivity(this._addButton, canAdd);
},
_onDestroy: function() {
- this.actor = null;
if (this._nWorkspacesNotifyId > 0) {
global.screen.disconnect(this._nWorkspacesNotifyId);
this._nWorkspacesNotifyId = 0;
}
- if (this._switchWorkspaceNotifyId > 0) {
- global.window_manager.disconnect(this._switchWorkspaceNotifyId);
- this._switchWorkspaceNotifyId = 0;
- }
},
_setButtonSensitivity: function(button, sensitive) {
button.opacity = sensitive ? 255 : 85;
},
- _updateButtonSensitivity: function() {
- this._setButtonSensitivity(this._addButton,
- this._currentView.canAddWorkspace());
- this._setButtonSensitivity(this._removeButton,
- this._currentView.canRemoveWorkspace());
- },
-
_workspacesChanged: function() {
- if (this.actor == null)
- return;
-
- this._updateButtonSensitivity();
-
if (global.screen.n_workspaces == 1)
this._toggleViewButton.hide();
else
this._toggleViewButton.show();
}
};
-
Signals.addSignalMethods(WorkspacesControls.prototype);
+
+function WorkspacesManager(width, height, x, y) {
+ this._init(width, height, x, y);
+}
+
+WorkspacesManager.prototype = {
+ _init: function(width, height, x, y) {
+ this._workspacesWidth = width;
+ this._workspacesHeight = height;
+ this._workspacesX = x;
+ this._workspacesY = y;
+
+ this._workspaces = [];
+ for (let w = 0; w < global.screen.n_workspaces; w++) {
+ let metaWorkspace = global.screen.get_workspace_by_index(w);
+ this._workspaces[w] = new Workspace.Workspace(metaWorkspace);
+ }
+
+ this.workspacesView = null;
+ this.controlsBar = new WorkspacesControls();
+ this._updateView();
+
+ this.controlsBar.actor.connect('destroy',
+ Lang.bind(this, this._onDestroy));
+ this._viewChangedId =
+ Shell.GConf.get_default().connect('changed::' + WORKSPACES_VIEW_KEY,
+ Lang.bind(this, this._updateView));
+ this._nWorkspacesNotifyId =
+ global.screen.connect('notify::n-workspaces',
+ Lang.bind(this, this._workspacesChanged));
+ this._switchWorkspaceNotifyId =
+ global.window_manager.connect('switch-workspace',
+ Lang.bind(this, this._updateControlsSensitivity));
+
+ },
+
+ _updateView: function() {
+ let viewType, newView;
+
+ let view = Shell.GConf.get_default().get_string(WORKSPACES_VIEW_KEY).toUpperCase();
+ if (view in WorkspacesViewType)
+ viewType = WorkspacesViewType[view];
+ else
+ viewType = WorkspacesViewType.SINGLE;
+
+ switch (viewType) {
+ case WorkspacesViewType.SINGLE:
+ newView = new SingleView(this._workspacesWidth,
+ this._workspacesHeight,
+ this._workspacesX,
+ this._workspacesY,
+ this._workspaces);
+ break;
+ case WorkspacesViewType.GRID:
+ default:
+ newView = new MosaicView(this._workspacesWidth,
+ this._workspacesHeight,
+ this._workspacesX,
+ this._workspacesY,
+ this._workspaces);
+ break;
+ }
+
+ if (this.workspacesView)
+ this.workspacesView.destroy();
+ this.workspacesView = newView;
+
+ this.controlsBar.updateControls(this.workspacesView);
+
+ this.emit('view-changed');
+ },
+
+ _workspacesChanged: function() {
+ let oldNumWorkspaces = this._workspaces.length;
+ let newNumWorkspaces = global.screen.n_workspaces;
+ let active = global.screen.get_active_workspace_index();
+
+ if (oldNumWorkspaces == newNumWorkspaces)
+ return;
+
+ let lostWorkspaces = [];
+ if (newNumWorkspaces > oldNumWorkspaces) {
+ // Assume workspaces are only added at the end
+ for (let w = oldNumWorkspaces; w < newNumWorkspaces; w++) {
+ let metaWorkspace = global.screen.get_workspace_by_index(w);
+ this._workspaces[w] = new Workspace.Workspace(metaWorkspace);
+ }
+ } else {
+ // Assume workspaces are only removed sequentially
+ // (e.g. 2,3,4 - not 2,4,7)
+ let removedIndex;
+ let removedNum = oldNumWorkspaces - newNumWorkspaces;
+ for (let w = 0; w < oldNumWorkspaces; w++) {
+ let metaWorkspace = global.screen.get_workspace_by_index(w);
+ if (this._workspaces[w].metaWorkspace != metaWorkspace) {
+ removedIndex = w;
+ break;
+ }
+ }
+
+ lostWorkspaces = this._workspaces.splice(removedIndex,
+ removedNum);
+
+ // Don't let the user try to select this workspace as it's
+ // making its exit.
+ for (let l = 0; l < lostWorkspaces.length; l++)
+ lostWorkspaces[l].setReactive(false);
+ }
+
+ this.workspacesView.updateWorkspaces(oldNumWorkspaces,
+ newNumWorkspaces,
+ lostWorkspaces);
+
+ this.controlsBar.setCanAdd(this.workspacesView.canAddWorkspace());
+ this.controlsBar.setCanRemove(this.workspacesView.canRemoveWorkspace());
+ },
+
+ _updateControlsSensitivity: function() {
+ this.controlsBar.setCanAdd(this.workspacesView.canAddWorkspace());
+ this.controlsBar.setCanRemove(this.workspacesView.canRemoveWorkspace());
+ },
+
+ _onDestroy: function() {
+ if (this._nWorkspacesNotifyId > 0)
+ global.screen.disconnect(this._nWorkspacesNotifyId);
+ if (this._switchWorkspaceNotifyId > 0)
+ global.window_manager.disconnect(this._switchWorkspaceNotifyId);
+ if (this._viewChangedId > 0)
+ Shell.GConf.get_default().disconnect(this._viewChangedId);
+ for (let w = 0; w < this._workspaces.length; w++)
+ this._workspaces[w].destroy();
+ }
+};
+Signals.addSignalMethods(WorkspacesManager.prototype);